package com.ssm.service.manager;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ssm.common.ImpoerModelUtil;
import com.ssm.common.util.layui.LayuiUnit;
import com.ssm.mapper.activiti.manager.ModelManagerMapper;
import com.ssm.vo.activiti.manager.BaseManagerQueryVo;
import com.ssm.vo.activiti.manager.BaseModelAddVo;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

@Service
public class ModelManagerService {
    @Resource
    private ModelManagerMapper modelManager;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private ImpoerModelUtil impoerModelUtil;

    /**
     * 获取查询结果
     *
     * @param modelManagerQueryVo
     * @return
     */
    public LayuiUnit queryActivitiModel(BaseManagerQueryVo modelManagerQueryVo) {
        String name = modelManagerQueryVo.getName();
        if (StringUtils.isNotEmpty(name)) {
            modelManagerQueryVo.setName("%" + name + "%");
        }
        String key = modelManagerQueryVo.getKey();
        if (StringUtils.isNotEmpty(key)) {
            modelManagerQueryVo.setKey("%" + key + "%");
        }

        Integer page = modelManagerQueryVo.getPage();
        Integer limit = modelManagerQueryVo.getLimit();
        modelManagerQueryVo.setBegincount((page - 1) * limit + 1);
        modelManagerQueryVo.setEndcount(page * limit);

        return LayuiUnit.data(modelManager.getModelCount(modelManagerQueryVo), modelManager.findModelList(modelManagerQueryVo));
    }

    /**
     * 批量删除Activiti Model
     *
     * @param ids
     */
    public void deleteModels(String ids) {
        String[] idArray = ids.split(",");
        for (String id : idArray) {
            if (StringUtils.isNotEmpty(id)) {
                repositoryService.deleteModel(id);
            }
        }
    }

    /**
     * 添加Activiti Model
     *
     * @param actReModelAddVo
     */
    public String saveModel(BaseModelAddVo actReModelAddVo) throws UnsupportedEncodingException {
        String modelID = creatModel(actReModelAddVo);

        String initBytesJson = actReModelAddVo.getInitBytesJson();
        if (StringUtils.isNotEmpty(initBytesJson)) {
            // 根据页面传输的信息初始化Model
            repositoryService.addModelEditorSource(modelID, initBytesJson.getBytes("utf-8"));

        } else {
            // 默认初始化
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.put("stencilset", stencilSetNode);
            repositoryService.addModelEditorSource(modelID, editorNode.toString().getBytes("utf-8"));
        }
        return modelID;

    }

    /**
     * 部署Activiti Model
     */
    public void deployment(String modelId) throws IOException {
        Model modelData = repositoryService.getModel(modelId);
        ObjectNode modelNode = (ObjectNode) new ObjectMapper()
                .readTree(repositoryService.getModelEditorSource(modelData.getId()));
        byte[] bpmnBytes = null;

        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
        bpmnBytes = new BpmnXMLConverter().convertToXML(model);

        String processName = modelData.getName() + ".bpmn20.xml";

        repositoryService.createDeployment()
                .name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8"))
                .deploy();

    }

    /**
     * 根据业务流程导入Model
     *
     * @param file
     * @param actReModelAddVo
     * @return
     */
    public String importModelByProcessResource(MultipartFile file, BaseModelAddVo actReModelAddVo) throws IOException {
        String modelID = creatModel(actReModelAddVo);
        impoerModelUtil.creatModelByImpoutStream(file.getInputStream(),modelID);
        return modelID;
    }


    /**
     * 创建Model
     * @param actReModelAddVo
     * @return
     */
    private String creatModel(BaseModelAddVo actReModelAddVo) {
        Model modelData = repositoryService.newModel();
        ObjectNode modelObjectNode = objectMapper.createObjectNode();
        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, actReModelAddVo.getName());
        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, actReModelAddVo.getDescription());
        modelData.setMetaInfo(modelObjectNode.toString());
        modelData.setName(actReModelAddVo.getName());
        modelData.setKey(actReModelAddVo.getKey());
        //保存模型
        repositoryService.saveModel(modelData);
        return modelData.getId();
    }

}
